/**
 * @file asyncnetworkmanager.h
 * @brief 异步网络管理器 - 高性能网络通信
 */

#ifndef ASYNCNETWORKMANAGER_H
#define ASYNCNETWORKMANAGER_H

#include <QObject>
#include <QThread>
#include <QWebSocket>
#include <QTimer>
#include <QQueue>
#include <QMutex>
#include <QJsonObject>
#include <QJsonDocument>

/**
 * @brief 异步网络管理器
 * 
 * 高性能网络特性：
 * 1. 独立网络线程
 * 2. 消息优先级队列
 * 3. 自动重连机制
 * 4. 延迟监控
 * 5. 消息压缩
 */
class AsyncNetworkManager : public QObject
{
    Q_OBJECT

public:
    explicit AsyncNetworkManager(QObject *parent = nullptr);
    ~AsyncNetworkManager();

    /**
     * @brief 消息优先级
     */
    enum MessagePriority {
        PRIORITY_LOW = 0,       // 低优先级（统计信息等）
        PRIORITY_NORMAL = 1,    // 普通优先级（游戏状态）
        PRIORITY_HIGH = 2,      // 高优先级（用户输入）
        PRIORITY_CRITICAL = 3   // 关键优先级（连接控制）
    };

    /**
     * @brief 网络消息结构
     */
    struct NetworkMessage {
        QJsonObject data;           // 消息数据
        MessagePriority priority;   // 优先级
        qint64 timestamp;           // 时间戳
        int retryCount;             // 重试次数
        QString messageId;          // 消息ID
        bool requiresAck;           // 是否需要确认
    };

    /**
     * @brief 网络统计
     */
    struct NetworkStats {
        int latency;                // 延迟(ms)
        int packetLoss;             // 丢包率(%)
        int bandwidth;              // 带宽(bytes/s)
        int messagesPerSecond;      // 消息/秒
        qint64 totalBytesSent;      // 总发送字节
        qint64 totalBytesReceived;  // 总接收字节
    };

public slots:
    /**
     * @brief 连接到服务器
     * @param url 服务器URL
     */
    void connectToServer(const QString &url);

    /**
     * @brief 断开连接
     */
    void disconnectFromServer();

    /**
     * @brief 发送消息（带优先级）
     * @param message 消息内容
     * @param priority 优先级
     * @param requiresAck 是否需要确认
     */
    void sendMessage(const QJsonObject &message, 
                    MessagePriority priority = PRIORITY_NORMAL,
                    bool requiresAck = false);

    /**
     * @brief 发送用户输入（最高优先级）
     * @param direction 方向
     * @param sequenceNumber 序列号
     */
    void sendUserInput(int direction, int sequenceNumber);

    /**
     * @brief 设置网络配置
     * @param enableCompression 启用压缩
     * @param maxRetries 最大重试次数
     * @param heartbeatInterval 心跳间隔(ms)
     */
    void setNetworkConfig(bool enableCompression, int maxRetries, int heartbeatInterval);

signals:
    /**
     * @brief 连接状态变化
     * @param connected 是否已连接
     */
    void connectionStateChanged(bool connected);

    /**
     * @brief 接收到游戏状态更新
     * @param gameState 游戏状态
     * @param serverTimestamp 服务器时间戳
     */
    void gameStateReceived(const QJsonObject &gameState, qint64 serverTimestamp);

    /**
     * @brief 接收到输入确认
     * @param sequenceNumber 序列号
     * @param serverTimestamp 服务器时间戳
     */
    void inputAcknowledged(int sequenceNumber, qint64 serverTimestamp);

    /**
     * @brief 网络统计更新
     * @param stats 网络统计
     */
    void networkStatsUpdated(const NetworkStats &stats);

    /**
     * @brief 网络错误
     * @param error 错误信息
     */
    void networkError(const QString &error);

private slots:
    /**
     * @brief WebSocket连接成功
     */
    void onConnected();

    /**
     * @brief WebSocket断开连接
     */
    void onDisconnected();

    /**
     * @brief 接收到消息
     * @param message 消息内容
     */
    void onMessageReceived(const QString &message);

    /**
     * @brief WebSocket错误
     * @param error 错误类型
     */
    void onSocketError(QAbstractSocket::SocketError error);

    /**
     * @brief 消息发送定时器
     */
    void onSendTimer();

    /**
     * @brief 心跳定时器
     */
    void onHeartbeatTimer();

    /**
     * @brief 统计定时器
     */
    void onStatsTimer();

private:
    /**
     * @brief 处理消息队列
     */
    void processMessageQueue();

    /**
     * @brief 发送下一条消息
     */
    void sendNextMessage();

    /**
     * @brief 处理接收到的消息
     * @param jsonObj 消息对象
     */
    void handleReceivedMessage(const QJsonObject &jsonObj);

    /**
     * @brief 更新网络统计
     */
    void updateNetworkStats();

    /**
     * @brief 计算延迟
     * @param serverTimestamp 服务器时间戳
     * @return 延迟(ms)
     */
    int calculateLatency(qint64 serverTimestamp);

    /**
     * @brief 压缩消息
     * @param data 原始数据
     * @return 压缩后数据
     */
    QByteArray compressMessage(const QByteArray &data);

    /**
     * @brief 解压消息
     * @param data 压缩数据
     * @return 解压后数据
     */
    QByteArray decompressMessage(const QByteArray &data);

private:
    // === 网络核心 ===
    QThread *m_networkThread;           // 网络线程
    QWebSocket *m_webSocket;            // WebSocket连接
    QString m_serverUrl;                // 服务器URL
    bool m_isConnected;                 // 连接状态
    
    // === 消息队列 ===
    QQueue<NetworkMessage> m_messageQueue;  // 消息队列
    QMutex m_queueMutex;                // 队列互斥锁
    QTimer *m_sendTimer;                // 发送定时器
    
    // === 心跳和重连 ===
    QTimer *m_heartbeatTimer;           // 心跳定时器
    QTimer *m_reconnectTimer;           // 重连定时器
    int m_heartbeatInterval;            // 心跳间隔
    int m_reconnectAttempts;            // 重连尝试次数
    
    // === 网络配置 ===
    bool m_compressionEnabled;          // 是否启用压缩
    int m_maxRetries;                   // 最大重试次数
    int m_sendInterval;                 // 发送间隔(ms)
    
    // === 统计和监控 ===
    QTimer *m_statsTimer;               // 统计定时器
    NetworkStats m_stats;               // 网络统计
    QList<qint64> m_latencyHistory;     // 延迟历史
    qint64 m_lastHeartbeatTime;         // 最后心跳时间
    
    // === 消息跟踪 ===
    QHash<QString, qint64> m_pendingAcks;   // 待确认消息
    int m_nextMessageId;                // 下一个消息ID
};

#endif // ASYNCNETWORKMANAGER_H
